package org.nimi317.web_gis.service.impl;

import jakarta.mail.MessagingException;
import org.apache.commons.lang3.RandomStringUtils;
import org.nimi317.web_gis.exception.E;
import org.nimi317.web_gis.exception.RException;
import org.nimi317.web_gis.service.IEmailService;
import org.nimi317.web_gis.service.IUserService;
import org.nimi317.web_gis.service.RedisService;
import org.nimi317.web_gis.utils.EmailUtils;
import org.nimi317.web_gis.utils.StringUtils;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author thunderobot
 */
@Service
public class IEmailServiceImpl implements IEmailService {

    private final EmailUtils emailUtils;

    private final RedisService redisService;

    private final IUserService userService;

    public IEmailServiceImpl(EmailUtils emailUtils, RedisService redisService, IUserService userService) {
        this.emailUtils = emailUtils;
        this.redisService = redisService;
        this.userService = userService;
    }

    @Override
    public void sendRegisterCaptcha(String email) {
        emailUtils.checkEmail(email);
        boolean exists = userService.existByEmail(email);
        if (exists) {
            throw new RException(E.UserRegisteredException);
        }
        String key = "register:" + email;
        Boolean hasKey = redisService.hasKey(key);
        if (hasKey) {
            throw new RException(E.EmailHasSendException);
        }
        String random = RandomStringUtils.random(5, 48, 90, true, true);
        try {
            emailUtils.sendEmail(
                    email,
                    "邮箱注册",
                    "<h1 style='text-align:center'>欢迎您注册本系统</h1><p>您的验证码为:</p><h2 style='text-align:center'>" + random + "</h2><p>有效期5分钟<p>");
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
        redisService.setCacheObject(key, random, 5L, TimeUnit.MINUTES);
    }

    @Override
    public void sendLoginCaptcha(String email) {
        emailUtils.checkEmail(email);
        boolean exist = userService.existByEmail(email);
        if (!exist) {
            throw new RException(E.UserNotFoundException);
        }
        // 检验是否已经存在
        String key = "login:" + email;
        Boolean hasKey = redisService.hasKey(key);
        if (hasKey) {
            throw new RException(E.EmailHasSendException);
        }
        String random = RandomStringUtils.random(5, 48, 90, true, true);
        try {
            emailUtils.sendEmail(
                    email,
                    "邮箱登录",
                    "<h1 style='text-align:center'>欢迎您登录本系统</h1><p>您的验证码为:</p><h2 style='text-align:center'>" + random + "</h2><p>有效期5分钟</p>");
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
        redisService.setCacheObject(key, random, 5L, TimeUnit.MINUTES);
    }

    @Override
    public void checkRegisterCaptcha(String email, String captcha) {
        emailUtils.checkEmail(email);
        check("register:", email, captcha);
    }

    @Override
    public void checkLoginCaptcha(String email, String captcha) {
        emailUtils.checkEmail(email);
        check("login:", email, captcha);
    }

    @Override
    public void removeLoginCaptcha(String email) {
        redisService.deleteObject("login:" + email);
    }

    @Override
    public void removeRegisterCaptcha(String email) {
        redisService.deleteObject("register:" + email);
    }

    private void check(String x, String email, String captcha) {
        String value = redisService.getCacheObject(x + email);
        if (StringUtils.isBlank(value)) {
            throw new RException(E.EmailCodeExpired);
        }
        if (!value.equals(captcha)) {
            throw new RException(E.EmailCodeErrorException);
        }
    }
}
